<template>
    <div class="app-container">
        <div class="filter-container">
                <el-input v-model="listQuery.name" placeholder="角色名称" style="width: 80px;" class="filter-item" @keyup.enter.native="handleFilter" />
                <el-input v-model="listQuery.code" placeholder="角色标识" style="width: 80px;" class="filter-item" @keyup.enter.native="handleFilter" />
                <base-select :dictType="'ROLE_TYPE'" v-model="listQuery.type" style="width: 140px" placeholder="角色类型" class="filter-item" @change="handleFilter">
                </base-select>
                <base-select :dictType="'BASE_STATUS'" v-model="listQuery.status" style="width: 140px" placeholder="状态" class="filter-item" @change="handleFilter">
                </base-select>
            <el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">
                {{ $t('table.search') }}
            </el-button>
            <el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="handleCreate">
                {{ $t('table.add') }}
            </el-button>
        </div>

        <el-table
                :key="tableKey"
                v-loading="listLoading"
                :data="list"
                border
                fit
                highlight-current-row
                style="width: 100%;margin-top:10px"
                @sort-change="sortChange"
        >
                <el-table-column label="角色ID" prop="id" sortable="true" align="center" width="80" v-if="false">
                    <template slot-scope="{row}">
                        <span>{{ row.id }}</span>
                    </template>
                </el-table-column>
                <el-table-column label="角色名称" prop="name" sortable="true" align="center" width="80" >
                    <template slot-scope="{row}">
                        <span>{{ row.name }}</span>
                    </template>
                </el-table-column>
                <el-table-column label="角色标识" prop="code" sortable="true" align="center" width="80" >
                    <template slot-scope="{row}">
                        <span>{{ row.code }}</span>
                    </template>
                </el-table-column>
                <el-table-column label="描述" prop="description" sortable="true" align="center" width="180" >
                    <template slot-scope="{row}">
                        <span>{{ row.description }}</span>
                    </template>
                </el-table-column>
                <el-table-column label="角色类型" prop="type" sortable="true" align="center" width="80" >
                    <template slot-scope="{row}">
                        <span>{{ row.type | dictValueFilter('ROLE_TYPE')}}</span>
                    </template>
                </el-table-column>
                <el-table-column label="权限编码" prop="authCode" sortable="true" align="center" width="80" >
                    <template slot-scope="{row}">
                        <span>{{ row.authCode | dictValueFilter('AUTH_CODE')}}</span>
                    </template>
                </el-table-column>
                <el-table-column label="状态" prop="status" sortable="true" align="center" width="80" >
                    <template slot-scope="{row}">
                        <span>{{ row.status | dictValueFilter('BASE_STATUS')}}</span>
                    </template>
                </el-table-column>
                <el-table-column label="更新人" prop="updateUserid" sortable="true" align="center" width="80" >
                    <template slot-scope="{row}">
                        <span>{{ row.updateUserid }}</span>
                    </template>
                </el-table-column>
                <el-table-column label="更新时间" prop="updateTime" sortable="true" align="center" width="180" >
                    <template slot-scope="{row}">
                        <span>{{ row.updateTime }}</span>
                    </template>
                </el-table-column>
            <el-table-column label="操作" align="center" width="300px" class-name="small-padding fixed-width">
                <template slot-scope="{row,$index}">
                    <el-button type="primary" size="mini" @click="handleUpdate(row)">
                        {{ $t('table.edit') }}
                    </el-button>
                    <el-button  size="mini" type="danger" @click="handleDelete(row,$index)">
                        {{ $t('table.delete') }}
                    </el-button>
                    <el-button  size="mini" type="warning" @click="handleAuth(row)">
                        配置权限
                    </el-button>
                </template>
            </el-table-column>
        </el-table>

        <pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" />

        <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
            <el-form ref="dataForm" :rules="rules" :model="temp"  label-width="120px" style="width: 300px; margin-left:50px;">
                    <el-form-item label="角色名称" prop="name">
                        <el-input v-model="temp.name" />
                    </el-form-item>
                    <el-form-item label="角色标识" prop="code">
                        <el-input v-model="temp.code" />
                    </el-form-item>
                    <el-form-item label="描述" prop="description">
                        <el-input v-model="temp.description" />
                    </el-form-item>
                    <el-form-item label="角色类型" prop="type">
                        <base-select :dictType="'ROLE_TYPE'" v-model="temp.type" class="filter-item" placeholder="Please select">
                        </base-select>
                    </el-form-item>
                    <el-form-item label="权限编码" prop="authCode">
                        <base-select :dictType="'AUTH_CODE'" v-model="temp.authCode" class="filter-item" placeholder="Please select">
                        </base-select>
                    </el-form-item>
                    <el-form-item label="状态" prop="status">
                        <base-select :dictType="'BASE_STATUS'" v-model="temp.status" class="filter-item" placeholder="Please select">
                        </base-select>
                    </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="dialogFormVisible = false">
                    {{ $t('table.cancel') }}
                </el-button>
                <el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">
                    {{ $t('table.confirm') }}
                </el-button>
            </div>
        </el-dialog>

        <el-dialog title="权限配置" :visible.sync="dialogAuthVisible" width="60%" @open="openAuthDialog()" @close="closeAuthDialog()">
            <el-tabs v-model="activeName" @tab-click="handleTabs" >
                <el-tab-pane label="菜单配置" name="menu_conf">
                    <!-- <el-input
                        placeholder="输入关键字进行过滤"
                        v-model="filterMenuText" style="width:150px">
                        </el-input>
                    <el-tree
                        :data="menuList"
                        show-checkbox
                        default-expand-all
                        node-key="id"
                        ref="menuTree"
                        highlight-current
                        :filter-node-method="filterMenuNode"
                        :props="{label:'menuName'}">
                        </el-tree> -->
                        <el-table
                            :data="menuList"
                            border
                            fit
                            size="mini"
                            highlight-current-row
                            row-key="id"
                            :default-expand-all="true"
                            :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
                            >
                            <el-table-column label="菜单名称" width="180">
                                <template slot-scope="scope">
                                    <el-checkbox 
                                        v-model="scope.row.checked" 
                                        :indeterminate="scope.row.indeterminate" 
                                        @change="handleCheckAllChange(scope.row, $event)"
                                        >
                                        {{ scope.row.menuName }}
                                    </el-checkbox>
                                </template>
                                </el-table-column>
                                <el-table-column label="功能选项">
                                <template v-if="scope.row.children.length === 0" slot-scope="scope">
                                <el-checkbox
                                    v-for="options in scope.row.pageElement"
                                    :key="options.id"
                                    v-model="options.checked"
                                    :label="options.elementName"
                                    @change="handleCheckChange(scope.row)"
                                />
                                </template>
                            </el-table-column>
                        </el-table>
                </el-tab-pane>
                <el-tab-pane label="权限配置" name="auth_conf">
                    <el-transfer
                        style="text-align: left; display: inline-block"
                        v-model="resourceIdArray"
                        filterable
                        :filter-method="filterAuthMethod"
                        :props="{key:'id'}"
                        :titles="['未选中', '已选中']"
                        :button-texts="['删除', '赋权']"
                        :format="{
                            noChecked: '${total}',
                            hasChecked: '${checked}/${total}'
                        }"
                        :data="operationList">
                        <span slot-scope="{ option }">{{ option.id }} - {{ option.operationUrl }}</span>
                    </el-transfer>
                    <!-- <el-transfer v-model="resourceIdArray" 
                        :data="operationList" 
                        :props="{key:'id'}"
                        >
                        <span slot-scope="{ option }">{{ option.id }} - {{ option.operationUrl }}</span>
                        </el-transfer> -->
                </el-tab-pane>
            </el-tabs>
            <div slot="footer" class="dialog-footer">
                <el-button @click="dialogAuthVisible = false" >
                    {{ $t('table.cancel') }}
                </el-button>
                <el-button type="primary" @click="activeName==='menu_conf'?handleMenuAndBtn():handleOperation()">
                    {{ $t('table.confirm') }}
                </el-button>
            </div>
        </el-dialog>
    </div>
</template>
<style>

 .el-transfer-panel{

  border: 1px solid #ebeef5;

  border-radius: 4px;

  overflow: hidden;

  background: #fff;

  display: inline-block;

  vertical-align: middle;

  width: 300px;

  -webkit-box-sizing: border-box;

  box-sizing: border-box;

  position: relative;

}

.el-transfer-panel .el-checkbox__label {
    font-size:12px;
}

</style>
<script>
    import { page , create, update, del,selectOne,menuTreeChecked,updateRoleResource,getRoleResource,roleOperation,updateRoleOperation } from '@/api/rbac/Role'
    import waves from '@/directive/waves' // waves directive
    import { parseTime } from '@/utils'
    import Pagination from '@/components/Pagination' // secondary package based on el-pagination
    import BaseSelect from '@/components/Dict'



    export default {
        name: 'role',
        components: { Pagination,BaseSelect },
        directives: { waves },
        filters: {
        },
        data() {
            return {
                tableKey: 0,
                list: null,
                total: 0,
                listLoading: true,
                listQuery: {
                    page: 1,
                    limit: 20,
                    sort: 'id desc',
                            name : '',
                            code : '',
                            description : '',
                            type : '',
                            status : ''
                },
                temp: {
                    name : '',
                    code : '',
                    description : '',
                    type : '',
                    parentId : '',
                    status : '',
                    authCode : ""
                },
                dialogFormVisible: false,
                dialogAuthVisible: false,
                activeName: 'menu_conf',
                menuList: null,
                operationList:[],
                filterMenuText:'',
                authRoleId:null,
                resourceIdArray:[],
                dialogStatus: '',
                textMap: {
                    update: '编辑',
                    create: '新增'
                },
                rules: {
                },
                downloadLoading: false,
                filterAuthMethod(query, item) {
                    if(query == ''){
                        return true
                    }
                    return item.operationUrl.indexOf(query) > -1;
                }
            }
        },
        created() {
            this.getList()
        },
        methods: {
            getList() {
                this.listLoading = true
                page(this.listQuery).then(response => {
                    this.list = response.data.list
                    this.total = response.data.total
                    this.listLoading = false
            })
            },
            handleFilter() {
                this.listQuery.page = 1
                this.getList()
            },
            handleModifyStatus(row, status) {
                this.$message({
                    message: '操作成功',
                    type: 'success'
                })
                row.status = status
            },
            sortChange(data) {
                const { prop, order } = data
                //   if (prop === 'id') {
                this.sortBy(prop,order)
                //   }
            },
            sortBy(prop,order) {
                if (order === 'ascending') {
                    this.listQuery.sort = prop + ' asc'
                } else {
                    this.listQuery.sort = prop + ' desc'
                }
                this.handleFilter()
            },
            resetTemp() {
                this.temp = {
                            name : '',
                            code : '',
                            description : '',
                            type : '',
                            status : '',
                            authCode : ''
                }
            },
            handleCreate() {
                this.resetTemp()
                this.dialogStatus = 'create'
                this.dialogFormVisible = true
                this.$nextTick(() => {
                    this.$refs['dataForm'].clearValidate()
                })
            },
            createData() {
                this.$refs['dataForm'].validate((valid) => {
                    if (valid) {
                        create(this.temp).then(() => {
                            this.dialogFormVisible = false
                            this.$notify({
                                title: '成功',
                                message: '创建成功',
                                type: 'success',
                                duration: 2000
                            })
                            this.getList()
                        })
                    }
                })
            },
            handleUpdate(row) {
                selectOne(row.id).then(response =>{
                    this.temp = response.data
                    this.dialogStatus = 'update'
                    this.dialogFormVisible = true
                    this.$nextTick(() => {
                        this.$refs['dataForm'].clearValidate()
                    })
            }).catch(error =>{
                    this.$notify({
                        title: '失败',
                        message: error,
                        type: 'error',
                        duration: 2000
                    })
                })

            },
            updateData() {
                this.$refs['dataForm'].validate((valid) => {
                    if (valid) {
                        const tempData = Object.assign({}, this.temp)
                        update(tempData).then(() => {
                        this.dialogFormVisible = false
                        this.$notify({
                            title: '成功',
                            message: '更新成功',
                            type: 'success',
                            duration: 2000
                        })
                        this.getList()
                    })
                    }
                })
            },
            handleDelete(row, index) {
                del(row.id).then(response =>{
                    this.$notify({
                        title: '成功',
                        message: '删除成功',
                        type: 'success',
                        duration: 2000
                    })
                    this.getList()
                }).catch(error =>{
                    this.$notify({
                        title: '删除失败',
                        message: error,
                        type: 'error',
                        duration: 2000
                    })
                })
            },
            handleAuth(row){ // 配置权限
                this.dialogAuthVisible = true
                this.authRoleId = row.id
            },
            closeAuthDialog(){
                // this.$refs.menuTree.setCheckedKeys([])
                this.resourceIdArray = []
                this.operationList = []
            },
            openAuthDialog(){
                menuTreeChecked().then(response =>{
                    this.menuList = response.data
                })
                // getRoleResource({roleId:this.authRoleId,type:'1'}).then(response =>{
                //     const roleResource = response.data
                //     let array = []
                //     roleResource.forEach(element => {
                //         array.push(element.resourceId)
                //     });
                //     this.$refs.menuTree.setCheckedKeys(array)
                // })
                roleOperation({roleId:this.authRoleId,type:'3'}).then(response =>{
                    let responseData = response.data
                    this.resourceIdArray = responseData.authChecked
                    this.operationList = responseData.operationList
                })
            },
            filterMenuNode(value, data){
                if (!value) return true;
                return data.menuName.indexOf(value) !== -1;
            },
            handleMenuAndBtn(){
                // const checkMenus = this.$refs.menuTree.getCheckedKeys().join(',')// 选中的菜单id
                updateRoleResource({roleId:this.authRoleId,menuList:this.menuList}).then(response =>{
                    this.$notify({
                        title: '成功',
                        message: '设置页面及按钮成功',
                        type: 'success',
                        duration: 2000
                    })
                    this.dialogAuthVisible=false
                    this.getList()
                }).catch(error =>{
                    this.$notify({
                        title: '设置页面及按钮失败',
                        message: error,
                        type: 'error',
                        duration: 2000
                    })
                })
            },
            handleOperation(){
                const resourceIds = this.resourceIdArray.join(',')
                updateRoleOperation({roleId:this.authRoleId,resourceIds:resourceIds,type:'3'}).then(response =>{
                    this.$notify({
                        title: '成功',
                        message: '设置权限成功',
                        type: 'success',
                        duration: 2000
                    })
                    this.dialogAuthVisible=false
                    this.getList()
                }).catch(error =>{
                    this.$notify({
                        title: '设置权限失败',
                        message: error,
                        type: 'error',
                        duration: 2000
                    })
                })
            },
            handleTabs(tab, event){
                this.activeName=tab.name
            },
             handleCheckAllChange(val, checked) {
                // 有下级去处理下级
                if (val.children.length > 0) {
                this.findChildren(val.children, checked)
                } else {
                // 无下级处理本级
                val.pageElement.forEach(options => { options.checked = checked })
                }
                // 处理上级
                if (val.parentId !== 0) {
                this.findParent(this.menuList, val.parentId)
                }
                val.indeterminate = false
            },
            handleCheckChange(val) {
                const length = val.pageElement.length
                let checkedLength = 0
                val.pageElement.forEach(options => {
                if (options.checked) {
                    checkedLength++
                }
                })
                val.checked = checkedLength === length
                val.indeterminate = checkedLength > 0 && checkedLength < length
                // 处理上级
                if (val.parentId !== 0) {
                this.findParent(this.menuList, val.parentId)
                }
            },
            findChildren(list, checked) {
                list.forEach(children => {
                children.checked = checked
                children.indeterminate = false
                children.pageElement.forEach(options => {
                    options.checked = checked
                    if (children.children.length > 0) {
                    this.findChildren(children.children, checked)
                    }
                })
                })
            },
            findParent(list, parentId) {
                list.forEach(result => {
                let parentCheckedLength = 0
                let parentIndeterminateLength = 0
                if (result.id === parentId) {
                    result.children.forEach(children => {
                    if (children.indeterminate) {
                        parentIndeterminateLength++
                    } else if (children.checked) {
                        parentCheckedLength++
                    }
                    })
                    result.checked = parentCheckedLength === result.children.length
                    result.indeterminate = (parentIndeterminateLength > 0 || parentCheckedLength > 0) && parentCheckedLength < result.children.length
                    if (result.parentId !== 0) {
                    this.findParent(this.menuList, result.parentId)
                    }
                } else if (result.children.length > 0) {
                    this.findParent(result.children, parentId)
                }
                })
            }
        },
        watch: {
            filterMenuText(val) {
                this.$refs.menuTree.filter(val);
            }
        },
    }
</script>
